/*
 * anima/space.cc - Generic CPU functions.
 * Copyright (C) 2007  Mikhail Vorozhtsov
 * See the LICENSE section of the README file for details.
 */

/* $Id$ */

#include HEADER (anima,cpu.hh)
#include HEADER (anima,mm.hh)
#include HEADER (anima,thread.hh)

START_NAMESPACE (anima)

typeof (cpu_t::cpus) cpu_t::cpus;

cpu_t *
cpu_t::create (id_t id)
{
  cpu_t *cpu = cpus.lookup_key (id);

  if (cpu)
    return NULL;

  cpu = (cpu_t *) mm::map (mm::CT_CPU);

  if (!cpu)
    return NULL;

  new (cpu) cpu_t ();

  cpu->id = id;
  cpu->threads = NULL;
  cpu->cur_thread = NULL;
  cpu->scheduler = NULL;
  cpu->backup_scheduler = NULL;
  cpu->state = STATE_FRESH;

  if (!cpu->init_instance ())
    {
      mm::unmap ((u64_t) cpu);
      return NULL;
    }

  cpus.insert (cpu);

  mm::activate (cpu);

  return cpu;
}

cpu_ref_t
cpu_t::get (id_t id)
{
  cpu_t *cpu = cpus.lookup_key (id);

  if (!cpu)
    return cpu_ref_t ();

  return cpu_ref_t (cpu);
}

void
cpu_t::set_scheduler (thread_t *thread)
{
  scheduler = thread;
}

void
cpu_t::add (thread_t *thread)
{
  if (!threads)
    {
      thread->prev_cpu = thread;
      thread->next_cpu = thread;
      threads = thread;
    }
  else
    {
      thread->prev_cpu = threads->prev_cpu;
      thread->next_cpu = threads;
      thread->prev_cpu->next_cpu = thread;
      thread->next_cpu->prev_cpu = thread;
    }
}

END_NAMESPACE

